package icu.d4peng.cloud.gateway.config;

import com.alibaba.fastjson.JSON;
import icu.d4peng.cloud.common.core.vo.ResultVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;

import java.util.Map;

/**
 * @author d4peng
 * @version 1.0.0
 * @date 2022-01-06 14:00
 * @description GlobalExceptionHandler:全局异常处理
 */
@Configuration
public class GlobalExceptionHandler extends AbstractErrorWebExceptionHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    public GlobalExceptionHandler(ErrorAttributes errorAttributes, WebProperties.Resources resources, ServerCodecConfigurer serverCodecConfigurer, ApplicationContext applicationContext) {
        super(errorAttributes, resources, applicationContext);
        super.setMessageWriters(serverCodecConfigurer.getWriters());
        super.setMessageReaders(serverCodecConfigurer.getReaders());
    }


    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
        return RouterFunctions.route(RequestPredicates.all(), request -> {
            Map<String, Object> errors = errorAttributes.getErrorAttributes(request, ErrorAttributeOptions.defaults());
            Throwable throwable = errorAttributes.getError(request);
            LOGGER.error(JSON.toJSONString(errors));
            LOGGER.error(JSON.toJSONString(throwable));
            ResultVO<Throwable> result = ResultVO.build((Integer) errors.get("status"), (String) errors.get("message"), throwable);
            return ServerResponse.status(HttpStatus.BAD_REQUEST).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue(result));
        });
    }
}
